package com.xbongbong.saas.model.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.ext.OptionalRangeEntity;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.OptionalRangeEnum;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.workreportset.pojo.WorkReportSetVisibleRange;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.domain.dao.WorkReportSetDao;
import com.xbongbong.saas.domain.entity.WorkReportSetEntity;
import com.xbongbong.saas.enums.business.WorkReportTypeEnum;
import com.xbongbong.saas.model.WorkReportSetModel;
import com.xbongbong.sys.domain.entity.DepartmentEntity;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.enums.DataPermissionEnum;
import com.xbongbong.sys.model.DepartmentModel;
import com.xbongbong.sys.model.UserModel;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author youli.chen
 * @ProjectName xbb-pro
 * @Description: TODO
 * @date 2019/1/17 9:58
 */
@Service("workReportSetModel")
public class WorkReportSetModelImpl implements WorkReportSetModel {

    @Resource
    private WorkReportSetDao workReportSetDao;
    @Resource
    private UserModel userModel;
    @Resource
    private DepartmentModel departmentModel;

    /**
     * 新增工作报告设置
     *
     * @param entity
     * @return
     */
    @Override
    public Integer insert(WorkReportSetEntity entity) {
        return this.workReportSetDao.insert(entity);
    }

    /**
     * 更新工作报告设置
     *
     * @param entity
     * @return
     */
    @Override
    public Integer update(WorkReportSetEntity entity) {
        return this.workReportSetDao.update(entity);
    }

    /**
     * 根据ID删除工作报告设置
     *
     * @param key
     * @param corpid
     * @return
     */
    @Override
    public Integer deleteByKey(Long key, String corpid) {
        return this.workReportSetDao.deleteByKey(key, corpid);
    }

    /**
     * 根据ID获取工作报告设置详情
     *
     * @param key
     * @param corpid
     * @return
     */
    @Override
    public WorkReportSetEntity getByKey(Long key, String corpid) {
        return this.workReportSetDao.getByKey(key, corpid);
    }

    /**
     * 根据条件查询工作报告设置列表
     *
     * @param param
     * @return
     */
    @Override
    public List<WorkReportSetEntity> findEntitys(Map<String, Object> param) {
        return this.workReportSetDao.findEntitys(param);
    }

    /**
     * 根据条件统计设置条数
     *
     * @param param
     * @return
     */
    @Override
    public Integer getEntitysCount(Map<String, Object> param) {
        return workReportSetDao.getEntitysCount(param);
    }

    @Override
    public List findEntitysWithoutSub(Map<String, Object> param) {
        return null;
    }

    @Override
    public WorkReportSetEntity getByType(Integer type, String corpid) {
        return workReportSetDao.getByType(type,corpid);
    }

    @Override
    public Integer deleteByIdIn(List<Long> idIn, String corpid) {
        if (Objects.isNull(idIn) || idIn.isEmpty()) {
            return 0;
        }
        return workReportSetDao.deleteByIdIn(idIn, corpid);
    }
    @Override
    public List<String> getCorpidList(){
        return workReportSetDao.getCorpidList();
    }

    @Override
    public WorkReportSetVisibleRange getVisibleRange(UserEntity userEntity) {
        WorkReportSetVisibleRange visibleRange = new WorkReportSetVisibleRange();
        // json字段排序
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", userEntity.getCorpid());
        param.put("del", DelEnum.NORMAL.getDel());
        List<WorkReportSetEntity> workReportSetList = findEntitys(param);

        visibleRange.setDayEnable(true);
        visibleRange.setWeekEnable(true);
        visibleRange.setMonthEnable(true);

        for (WorkReportSetEntity workReportSet : workReportSetList) {
            if (Objects.equals(workReportSet.getEnable(), BasicConstant.NO_USE)) {
                disabledJsonWorkReportSet(visibleRange, workReportSet);
            }
            if (!checkUserWorkReportEnabled(userEntity, workReportSet)) {
                disabledJsonWorkReportSet(visibleRange, workReportSet);
            }
        }
        return visibleRange;
    }
    /**
     * 判断用户是有有操作工作报告的能力
     *
     * @param userEntity    用户实体
     * @param workReportSet 工作报告设置实体
     * @return
     * @throws
     * @author hongxiao
     * @date: 2019-03-13 16:06
     * @version v1.0
     * @since v1.0
     */
    private boolean checkUserWorkReportEnabled(UserEntity userEntity, WorkReportSetEntity workReportSet) {
        if (Objects.equals(userModel.getDataPermission(userEntity, true), DataPermissionEnum.ALL.getCode())) {
            return true;
        }
        List<OptionalRangeEntity> list = new ArrayList<>();
        if (workReportSet != null && workReportSet.getVisibleObject() != null) {
            try {
                list = workReportSet.getVisibleObject().toJavaList(OptionalRangeEntity.class);
            } catch (JSONException e) {
                list = new ArrayList<>();
            }
        }

        if (list.size() == 0) {
            return true;
        }

        List<String> userIdList = new ArrayList<>();
        List<String> roleIdList = new ArrayList<>();
        List<String> departmentIdList = new ArrayList<>();
        for (OptionalRangeEntity rangeEntity : list) {
            String property = rangeEntity.getProperty();
            String id = rangeEntity.getId();
            if (OptionalRangeEnum.DEPT.getValue().equals(property)) {
                departmentIdList.add(id);
            } else if (OptionalRangeEnum.ROLE.getValue().equals(property)) {
                roleIdList.add(id);
            } else if (OptionalRangeEnum.USER.getValue().equals(property)) {
                userIdList.add(id);
            }
        }
        if (userIdList.size() == 0 && roleIdList.size() == 0 && departmentIdList.size() == 0) {
            // 三个权限设置都为空，默认给予用户新建工作报告的功能
            return true;
        }

        if (!userIdList.contains(userEntity.getUserId())) {
            List<String> userRoles = StringUtil.roleIdToList(userEntity.getRoleIds());
            if (userRoles == null) {
                userRoles = new ArrayList<>();
            }
            userRoles.retainAll(roleIdList);
            if (userRoles.size() == 0) {
                List<String> userDepIdList = JSON.parseArray(userEntity.getDepartment(), String.class);
                if (userDepIdList.size() == 0 || departmentIdList.size() == 0) {
                    // 数据异常，不可能存在没有部门的员工
                    // 或设置的用户不为空且用户不在设置的用户列表里，而设置角色和部门是空的（反推得出此结论）
                    return false;
                } else {
                    Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    params.put("corpid", userEntity.getCorpid());
                    params.put("idIn", userDepIdList);
                    params.put("del", 0);
                    params.put("columns", "dep_id_router");
                    List<DepartmentEntity> userDepList = departmentModel.findEntitys(params);
                    if (userDepList.size() == 0) {
                        // 数据异常，不可能存在没有部门的员工
                        return false;
                    } else {
                        List<String> packagedWorkReportSetDepIdList = new ArrayList<>();
                        String tempVirgule = "|";
                        for (String workReportDepId : departmentIdList) {
                            packagedWorkReportSetDepIdList.add(tempVirgule + workReportDepId + tempVirgule);
                        }
                        boolean isSetDepIn = false;
                        for (DepartmentEntity department : userDepList) {
                            for (String packagedWorkReportSetDepId : packagedWorkReportSetDepIdList) {
                                isSetDepIn = department.getDepIdRouter().contains(packagedWorkReportSetDepId);
                                if (isSetDepIn) {
                                    break;
                                }
                            }
                            if (isSetDepIn) {
                                break;
                            }
                        }
                        if (!isSetDepIn) {
                            return false;
                        }
                    }
                }
            }
        }
        return true;
    }
    /**
     * 根据工作报告设置，添加日报、周报、月报的开启配置
     *
     * @param visibleRange  配置实体
     * @param workReportSet 工作报告实体
     * @return
     * @throws
     * @author hongxiao
     * @date: 2019-03-13 16:07
     * @version v1.0
     * @since v1.0
     */
    private void disabledJsonWorkReportSet(WorkReportSetVisibleRange visibleRange, WorkReportSetEntity workReportSet) {
        WorkReportTypeEnum typeEnum = WorkReportTypeEnum.getByType(workReportSet.getType());
        if (typeEnum == null) {
            return;
        }

        switch (typeEnum) {
            default:
                break;
            case DAILY:
                visibleRange.setDayEnable(false);
                break;
            case WEEKLY:
                visibleRange.setWeekEnable(false);
                break;
            case MONTHLY:
                visibleRange.setMonthEnable(false);
                break;
        }
    }

}
